闲话 22.7.27

闲话

?不知道为啥最近没啥好写的闲话了。(这句话是假的 - By 写完闲话的周
但最近总把闲话看成题解 忽略了闲话的功能

说起来闲话这玩意是谁先写的呢
看yspm说是一个叫dottle的人
猜测他一定很温柔吧
但是有人把闲话给锁起来算是什么啊 是在写日记吗?

最近在看yspm的博客 闲话功力我是无法企及的
就那种十分随意畅快的文字 是我一直很喜爱的
于是看到踩键消失了
抱着好奇的态度检查元素
点开了在赞键旁边的一个不明div,class名叫做buryit的
然后发现这玩意的display属性是none
大为震撼的同时把它改成了block
踩键出现了
于是踩了

相比之下不是很想和他人交往的我在最初就把大部分和读者交流的模块都删干净了
踩呢? - By Broken_Eclipse

先前说想学画画 可是似乎我有时间都用在翻译上了 口是心非

感觉我写闲话就是一句一断 而不像是正式语气那种拘束 我也不是喜欢拘束的人
这种写法似乎很受轻小说的影响 确实(

为什么昨天的闲话没人看啊 是因为晚上推流吗
还是因为当时发犇犇的人多啊
终于理解那些没推流的vup了(

区间线性基

CF1100F

给定长度为 \(n\) 的序列 \(\text a\)\(q\) 次询问,每次给定 \(l, r\),询问 \([l,\ r]\) 区间内异或最大值。

\(n,q \le 5e5,\text{size} = \max\{\ a[i]\ \} \le 1e18\)

第一眼似乎ST表,但ST表的空间复杂度在本题达到了 \(O(n \log n \log\text{size})\),拿计算机一算发现内存爆了。于是ST表pass。

又想到线段树暴力维护,反正空间开的下。然而,据我在上一篇闲话里分析的,线段树单次查询的时间复杂度为 \(O( \log n \log^2 \text{size})\),拿计算机一算发现时间爆了。于是线段树pass。

于是开始 借鉴题解。于是找到了一种很优秀的处理区间线性基的做法,预处理+查询都是 \(O(n \log \text{size})\) 的。

具体地,我们考虑前缀线性基的可能性。我们首先记录目前前缀的线性基 \(\text{lb}[ i]\),以及影响了线性基第 \(i\) 位的数字下标 \(\text{pos}[ i]\)。我们需要维护一个性质:当目前的线性基对应 \([1,\ r]\) 区间时,其中 \(\text{pos}[i] > l\) 的数构成的线性基就是 \([l,\ r]\) 区间对应的线性基。

这点可以通过贪心的思想得到维护方案:让 \(\text{pos}[i]\) 的值尽可能大。假设我们插入一个位于 \(w\) 的值 \(val\),当插入到第 \(i\) 位时,若 \(w > \text{pos}[i]\),那就将 \(\text{lb}[ i]\)\(val\) 交换,\(\text{pos}[i]\)\(w\) 交换,继续插入新的值。

代码:

struct Pref_Linear_Basis {
	#define plb Pref_Linear_Basis
	int p[25], pos[25];
	void init() {
		memset(p, 0, sizeof p);
		memset(pos, 0, sizeof pos);
	}
	void insert(const plb & proto, int w, int val) {
		*this = proto;
		pre(i,24,0) {
			if (val & (1<<i)) {
				if(p[i] == 0) {
					p[i] = val, pos[i] = w;
					return;
				} else if (pos[i] < w) {
					swap(pos[i], w);
					swap(p[i], val);
				} val ^= p[i];
			}
		}
	} 
	int qry(int l) {
		int ret = 0;
		pre(i,24,0) {
			if (p[i] and pos[i] >= l) ret = max(ret, ret ^ p[i]);
		} return ret;
	} 
} pref[N];	

int qry(int L, int R) {
	return pref[R].qry(L);
}

void init() {
	rep(i,1,n) {
		get(t1);
		pref[i].insert(pref[i-1], i, t1);
	}
}
posted @ 2022-07-27 17:42  joke3579  阅读(88)  评论(4编辑  收藏  举报